#define PCRE2_CODE_UNIT_WIDTH 8
#include "pcre2.h"
#include <stdio.h>
#include <string.h>

static int a = 1;

pcre2_code* compile(char *pattern){
    pcre2_code *re;
    int errornumber;
    PCRE2_SIZE erroroffset;
    re = pcre2_compile(
            pattern,
            PCRE2_ZERO_TERMINATED,
            0,
            &errornumber,
            &erroroffset,
            NULL);
    if (re == NULL)
    {
        PCRE2_UCHAR buffer[256];
        pcre2_get_error_message(errornumber, buffer, sizeof(buffer));
        printf("compile failed at offset %d: %s\n", (int)erroroffset,buffer);
        return NULL;
    }
    return re;
}

int preg_match(char *pattern, char *subject, char*** matches) {
    int rc;
    PCRE2_SIZE *ovector;

    pcre2_code *compiled_re = compile(pattern);

    PCRE2_SPTR pcre2_subject = (PCRE2_SPTR)subject;
    size_t subject_length = strlen((char *)subject);

    pcre2_match_data *match_data;

    match_data = pcre2_match_data_create_from_pattern(compiled_re, NULL);
    rc = pcre2_match(
            compiled_re,
            pcre2_subject,
            subject_length,
            0,
            0,
            match_data,
            NULL);

    if (rc < 1) {
        pcre2_match_data_free(match_data);
        pcre2_code_free(compiled_re);
        return 0;
    }

    ovector = pcre2_get_ovector_pointer(match_data);

    *matches = malloc(rc * sizeof(char*));

    for (int i = 0; i < rc; i++)
    {
        PCRE2_SPTR substring_start = pcre2_subject + ovector[2*i];
        size_t substring_length = ovector[2*i+1] - ovector[2*i];
        (*matches)[i] = strndup((char *)substring_start, (int)substring_length);
    }

    return rc;
}
